#ifndef GAMEENGINE_GEOMETRY_SPHERE_H
#define GAMEENGINE_GEOMETRY_SPHERE_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/Location/point3d.h>
#include <GameEngine/Geometry/Lines/line3d.h>
#include <GameEngine/Geometry/Core/angle.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Class used to represent 3D spheres
/*!
 @note A sphere is a volumetric object represented by its center and its radius
 @note Most algorithms expect floating point operations. Type T should therefore
       not be an integer type
 */
template <class T>
class Sphere {

public:
	Sphere();
	Sphere(const Point3d<T>& center, const T& radius);
	Sphere(const Sphere& rhs);
	virtual ~Sphere();
	Sphere& operator=(const Sphere& rhs);

	Point3d<T>& center();
	const Point3d<T>& center() const;
	T& radius();
	const T& radius() const;

	T diameter() const;
	T area() const;
	T volume() const;

	bool inside(const Point3d<T>& rhs, bool strict = false) const;
	int intersection(const Line3d<T>& rhs, T& coordinate1, T& coordinate2, IntersectionType::Type* type = nil) const;
	void closest_point(Angle<T>& azimuth, Angle<T>& dip, const Point3d<T>& rhs) const;
	Point3d<T> closest_point(const Point3d<T>& rhs) const;

	Point3d<T> point(const Angle<T>& azimuth, const Angle<T>& dip) const;
	void get_azimuth_and_dip(Angle<T>& azimuth, Angle<T>& dip, T& length, const Point3d<T>& rhs) const;

protected:
	//! Center of the sphere
	Point3d<T> center_;

	//! Radius of the sphere
	T radius_;
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Volumes/sphere.hpp>

#endif
